package com.twotwoshop.service.search.listener;

import cn.hutool.json.JSONUtil;
import com.twotwoshop.commom.es.EsConstants;
import com.twotwoshop.commom.rabbitmq.RabbitConstants;
import com.twotwoshop.commom.redis.RedisConstants;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
@RequiredArgsConstructor
public class SyncGoodsListener {


    private final StringRedisTemplate stringRedisTemplate;

    private final RestHighLevelClient client;


    /**
     * 监听es索引创建消息
     */
    @RabbitListener( bindings = @QueueBinding(
            value = @Queue(name = RabbitConstants.TWOTWO_GOODS_TOPIC),
            exchange = @Exchange(name = RabbitConstants.TWOTWO_GOODS_EXCHANGE,type = ExchangeTypes.DIRECT)
    ))
    @Transactional(rollbackFor = Exception.class)
    public void onMessage(Map<String, Object> esDocument){

        //如果获取成功
        if (esDocument!=null){
            //如果为添加新商品
            if (esDocument.get(RabbitConstants.ACTION).equals(RabbitConstants.ACTION_ADD)){

                saveGoodsEs(esDocument);


            }else

            //如果为更改商品信息
            if (esDocument.get(RabbitConstants.ACTION).equals(RabbitConstants.ACTION_UPDATE)){

                //更改es信息
                deleteGoodsEs(esDocument);
                saveGoodsEs(esDocument);


                //更改Redis
                deleteGoodsRedis(esDocument);


            }else

            //如果为删除商品
            if (esDocument.get(RabbitConstants.ACTION).equals(RabbitConstants.ACTION_DELETE)){

                //
                deleteGoodsEs(esDocument);

                //
                deleteGoodsRedis(esDocument);

            }
        }else{
            log.error("获取用户凭证失败");
            return;
        }

    }

    //1.删除商品数据到Redis
    public void deleteGoodsRedis(Map<String, Object> esDocument) {

        //删除rabbti识别的key 防止存入报错
        esDocument.remove(RabbitConstants.ACTION);

        //获取获取货物的id
        String id = (String)esDocument.get("id");

        Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries(RedisConstants.GOODS_DETAIILS_KEY + id);
        if (entries != null){

            //3.将数据到Redis中删除
           // stringRedisTemplate.opsForHash().delete(RedisConstants.GOODS_DETAIILS_KEY+id);
            stringRedisTemplate.delete(RedisConstants.GOODS_DETAIILS_KEY+id);
        }

        //删除商品浏览量
        stringRedisTemplate.opsForZSet().remove(RedisConstants.GOODS_VIEWS_KEY,id);

    }



    // 删除es文档数据
    private void deleteGoodsEs(Map<String, Object> esDocument) {

        //删除rabbtit识别的key 防止存入报错
        esDocument.remove(RabbitConstants.ACTION);

        //
        String id = (String)esDocument.get("id");


        // 1. 构建更改请求
        DeleteRequest deleteRequest = new DeleteRequest(EsConstants.ES_PRODUCTS, id);

        try {
            // 2. 发送删除请求到Elasticsearch
            DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);

            // 3. 处理响应，例如检查删除是否成功
            if (deleteResponse.getResult() == DocWriteResponse.Result.DELETED) {
                System.out.println("es中商品被删除");
            } else {
                System.out.println("es中商品状态删除失败");
            }
        } catch (IOException e) {
            // 4. 处理可能的异常
            e.printStackTrace();
        }
    }



    //2.写入数据到es
    private void saveGoodsEs(Map<String, Object> esDocument) {

        //删除rabbtit识别的key 防止存入报错
        esDocument.remove(RabbitConstants.ACTION);


        String id = (String)esDocument.get("id");


        // 5. 将文档写入 Elasticsearch
        IndexRequest indexRequest = new IndexRequest(EsConstants.ES_PRODUCTS)
                .id(id) // 设置文档的_id
                .source(esDocument, XContentType.JSON);

        try {
            client.index(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }



}












